package router

import (
	"gitee.com/mangenotwork/game-douniu/api/handler"
	"github.com/gin-gonic/gin"
	"github.com/mangenotwork/common/conf"
	"github.com/mangenotwork/common/ginHelper"
	"github.com/mangenotwork/common/log"
	"github.com/mangenotwork/common/utils"
)

var Router *gin.Engine

func init() {
	Router = gin.Default()
}

func Routers() *gin.Engine {

	//Router.Use(cors.New(cors.Config{
	//	AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},             //允许的方法
	//	AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization"}, //header允许山高月小
	//	AllowCredentials: false,
	//	MaxAge:           12 * time.Hour, //有效时间
	//	ExposeHeaders:    []string{"Content-Length"},
	//	AllowOriginFunc: func(origin string) bool { //允许的域
	//		return true //所有
	//	},
	//}))

	Router.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, Authorization")
		c.Next()
	})

	Router.GET("/", ginHelper.Handle(handler.Index))

	// 【登录接口】 登录成功后返回token 后续接口鉴权header传这个token
	Router.POST("/login", ginHelper.Handle(handler.Login))
	// 【注册接口】账号密码注册
	Router.POST("/register", ginHelper.Handle(handler.Register))

	// 【上传头像】
	Router.POST("/upload", ginHelper.Handle(handler.Upload))

	// 【头像静态资源获取】
	Router.Static("/img", "./img")

	// APP下载地址  /download/app.apk
	Router.Static("/download", "./download")

	// 上传Apk
	Router.POST("/add/apk", ginHelper.Handle(handler.AddAPK))

	// 上传文件
	Router.POST("/add/file", ginHelper.Handle(handler.AddFile))

	Router.Static("/file", "./file")

	// 测试计算牌结果
	Router.GET("/test", ginHelper.Handle(handler.Text))
	Router.GET("/test/niu", ginHelper.Handle(handler.TNiu))
	Router.GET("/test/vs", ginHelper.Handle(handler.TNiuVs))
	Router.GET("/test/bp", ginHelper.Handle(handler.TBianPai))

	// 设置指定玩家为VIP
	Router.GET("/user/vip/set", ginHelper.Handle(handler.UserSetVIP))
	Router.GET("/user/vip/del", ginHelper.Handle(handler.UserDeleteVIP))

	// 游戏初始化拉取信息
	Router.GET("/conf", ginHelper.Handle(handler.GameConf))

	// ios
	Router.GET("/ios/add", ginHelper.Handle(handler.IosAdd))                // 添加 ios.uuid
	Router.GET("/ios/link", ginHelper.Handle(handler.GameConf))             // 获取ios下载地址
	Router.GET("/ios/list", ginHelper.Handle(handler.IosList))              // 获取 ios uuid 列表
	Router.GET("/ios/agree", ginHelper.Handle(handler.IosAgree))            // 同意或拒绝 ios uuid
	Router.GET("/ios/agree/state", ginHelper.Handle(handler.IosAgreeState)) // 同意状态

	Api := Router.Group("") // , Auth())
	{
		// 首页，全局：【玩家基础信息接口】 玩家基础信息
		Api.GET("/user/:userId", ginHelper.Handle(handler.UserInfo))

		// 首页: 【游戏记录接口】 游戏记录
		Api.GET("/user/game/record", ginHelper.Handle(handler.UserGameRecord))

		// 首页: 【创建房间接口】创建房间
		Api.GET("/room/new/:userId", ginHelper.Handle(handler.NewRoom))

		// 首页: 【加入房间接口】加入房间
		Api.GET("/room/join", ginHelper.Handle(handler.JoinRoom))

		// <弃用> 房间: 用户准备or取消准备
		Api.GET("/room/ready", ginHelper.Handle(handler.UserReadyRoom))

		// <弃用> 房间: 【房间信息接口】房间人数信息， 轮询调用每1秒调用一次;
		Api.GET("/room/info/:roomId", ginHelper.Handle(handler.GetRoomInfo))

		// 玩家退出房间
		Api.GET("/room/out", ginHelper.Handle(handler.UserOutRoom))

		// 房主解散房间
		Api.GET("/room/dissolution", ginHelper.Handle(handler.DissolutionRoom))

		// 【开始按钮接口】开始游戏   不用管房间其他玩家准备， 状态变更为1
		Api.GET("/game/start", ginHelper.Handle(handler.GameStart))

		// 【准备接口】 状态1(待准备) 所有玩家调用，
		Api.GET("/game/ready", ginHelper.Handle(handler.GameReady))

		// 【开始选庄闲接口】状态1(待准备) 由房主调用前置条件是所有玩家准备，状态变更为 2(未确认庄闲)
		Api.GET("/game/vocation/select", ginHelper.Handle(handler.GameVocationSelect))

		// 【选择庄闲接口】 状态2(未确认庄闲)要当庄的那个人调用，状态变更为 3(待发牌)
		Api.GET("/game/vocation/set", ginHelper.Handle(handler.GameSetMaster))

		// 【发牌接口】状态3(待发牌)由庄家调用,游戏状态接口会返回牌信息，状态变更为 4(下注阶段)
		Api.GET("/game/deal", ginHelper.Handle(handler.GameDeal))

		// 游戏中: 【下注接口】玩家交互-下注
		Api.GET("/game/bet", ginHelper.Handle(handler.GameBet))

		// <弃用> 游戏中: 【投降接口】玩家交互-投降
		Api.GET("/game/surrender", ginHelper.Handle(handler.GameSurrender))

		//【游戏状态接口】 轮询获取游戏状态信息
		Api.GET("/game/state", ginHelper.Handle(handler.GameState))

		// todo 获取用户状态，用于app切后台导致用户离开当前房间或游戏 - not doc
		Api.GET("/user/state", ginHelper.Handle(handler.UserState))

		// 【本轮结算结果接口】状态7(本轮结束)所有玩家调用，返回本轮结算结果，未满10轮读秒时间结束后状态变为 3(待发牌)
		Api.GET("/game/item/result", ginHelper.Handle(handler.GameItemResult))

		// 【本局结算结果接口】 状态8(本局游戏结束) 所有玩家调用 , 时间到状态变为 1(待准备)
		Api.GET("/game/final/result", ginHelper.Handle(handler.GameFinalResult))

		// 用户修改信息
		Api.POST("/user/modify", ginHelper.Handle(handler.UserModify))

		// 换牌接口
		Api.GET("/game/change", ginHelper.Handle(handler.GameChange))

	}

	Router.POST("/login/admin", ginHelper.Handle(handler.AdminLogin))
	Router.POST("/set/admin/token", ginHelper.Handle(handler.SetAdminToken))
	Admin := Router.Group("/admin", AdminAuth())
	{
		Admin.Any("/home/data", ginHelper.Handle(handler.HomeData))
		Admin.Any("/user/list", ginHelper.Handle(handler.UserList))
		Admin.Any("/user/game/list", ginHelper.Handle(handler.UserGameList))
		Admin.Any("/vip/set", ginHelper.Handle(handler.UserSetVIP))
		Admin.Any("/vip/del", ginHelper.Handle(handler.UserDeleteVIP))
		Admin.Any("/room/list", ginHelper.Handle(handler.RoomList))
		Admin.Any("/conf/info", ginHelper.Handle(handler.GameConf))
		Admin.Any("/conf/update", ginHelper.Handle(handler.GameConfUpdate))
		Admin.Any("/add/apk", ginHelper.Handle(handler.AddAPK))
	}

	return Router
}

// 鉴权
func Auth() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.GetHeader("token")
		j := utils.NewJWT(conf.Conf.Default.Jwt.Secret, conf.Conf.Default.Jwt.Expire)
		if err := j.ParseToken(token); err == nil {
			c.Next()
			return
		}
		ginHelper.AuthErrorOut(c)
		c.Abort()
		return
	}
}

// admin 鉴权
// 跨服务鉴权方案
// 1. login 写入admin的token在内存
// 2. 接口请求传入admin的token进行比对
func AdminAuth() gin.HandlerFunc {
	return func(c *gin.Context) {
		user, err := c.Cookie("user")
		token, err := c.Cookie("sing")
		if err != nil {
			goto Out
		}
		//user := c.GetHeader("user")
		//token := c.GetHeader("sing")

		log.Info("user = ", user)
		log.Info("token = ", token)

		if handler.AdminTokenGet(&handler.SetAdminTokenReq{
			User:  user,
			Token: token,
		}) {
			c.Next()
			return
		}
	Out:
		ginHelper.AuthErrorOut(c)
		c.Abort()
		return
	}
}
